package com.ruoyi.system.controller;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.summary.AnnualMetrics;
import com.ruoyi.system.domain.summary.ProjectSummary;
import com.ruoyi.system.domain.summary.SectorSummary;
import com.ruoyi.system.domain.summary.Summary;
import com.ruoyi.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;

/**
 * 项目Controller
 * 
 * @author xuliang
 * @date 2024-03-29
 */
@RestController
@RequestMapping("/system/projectInfo")
@Slf4j
public class ProjectInfoController extends BaseController
{
    @Autowired
    private IProjectInfoService projectInfoService;
    @Autowired
    private IProcurementDetailService procurementDetailService;
    @Autowired
    private ILaborService laborService;
    @Autowired
    private IDirectService directService;
    @Autowired
    private IIndirectService indirectService;
    @Autowired
    private IOutputService outputService;

    @Autowired
    private ISysUserService userService;


    /**
     * 查询项目列表
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:list')")
    @GetMapping("/list")
    public Map<String,Object> list(ProjectInfo projectInfo)
    {

        projectInfoService.updateDirectSummary("",false);
        projectInfoService.updateItemSummary("",false);
        projectInfoService.updateDirectSummary("",false);
        projectInfoService.updateDirectSummary("",false);

        projectInfoService.updateProjectInfoBeforeGet("","");

        List<String> projectCodeList = projectInfoService.getContractByAreaId(projectInfo.getAreaId());
        List<String> contractNameList = projectInfoService.getContractNameByAreaId(projectInfo.getAreaId());

        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("projectCodeList",projectCodeList);
        dataMap.put("contractNameList",contractNameList);

        startPage();

        List<ProjectInfo> projectInfoList = projectInfoService.selectProjectInfoList(projectInfo);

        dataMap.put("dataList",getDataTable(projectInfoList));

        return dataMap;
    }


    /**
     * 获取项目详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(projectInfoService.selectProjectInfoById(id));
    }

    /**
     * 新增项目
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:add')")
    @Log(title = "项目", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ProjectInfo projectInfo)
    {
        if(projectInfoService.checkContractByNameAndCode(projectInfo.getProjectName(),projectInfo.getProjectCode()) == 0){
            return error("该项目尚未签订合同");
        }

        projectInfo.setProjectCode(projectInfoService.getProjectCodeByName(projectInfo.getProjectName()));
        projectInfo.setTotalContract(projectInfoService.getProjectContractByName(projectInfo.getProjectName()));

        // 查看数据库中的记录数量
        switch (projectInfoService.checkProjectByNameAndCode(projectInfo.getProjectName(),projectInfo.getProjectCode())){
            case 0:

                projectInfo.setDateNumber(DateUtils.getMonth());

                long userId = projectInfoService.getNewestUserId();

                SysUser user1 = new SysUser();
                SysUser user2 = new SysUser();
                user1.setUserId(userId + 1);
                user1.setDeptId(getDeptId());
                user1.setRoleIds(new Long[]{RoleUtils.getRole(projectInfo.getAreaId(), "F")});
                user1.setUserName(projectInfo.getProjectCode() + "F");
                user1.setNickName("系统用户");
                user1.setPassword(SecurityUtils.encryptPassword("123456"));
                user1.setRemark("财务");
                user2.setUserId(userId + 2);
                user2.setDeptId(getDeptId());
                user2.setRoleIds(new Long[]{RoleUtils.getRole(projectInfo.getAreaId(), "B")});
                user2.setUserName(projectInfo.getProjectCode() + "B");
                user2.setNickName("系统用户");
                user2.setPassword(SecurityUtils.encryptPassword("123456"));
                user2.setRemark("预算员");

                projectInfoService.insertProjectUser(projectInfo.getProjectCode(),user1.getUserId());
                projectInfoService.insertProjectUser(projectInfo.getProjectCode(),user2.getUserId());

                List<SysUser> userList = new ArrayList<>();
                userList.add(user1);
                userList.add(user2);
                for (SysUser user : userList) {
                    if (!userService.checkUserNameUnique(user))
                    {
                        return error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
                    }
                    else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
                    {
                        return error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
                    }
                    else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
                    {
                        return error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
                    }
                    user.setCreateBy(getUsername());
                    userService.insertUser(user);
                }

                projectInfo.setCreateBy(getUsername());
                projectInfo.setCreateTime(DateUtils.getNowDate());

                return toAjax(projectInfoService.insertProjectInfo(projectInfo));
            case 1:
                return error("项目名称与编号不可重复");
        }

        return toAjax(false);

    }

    /**
     * 修改项目
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:edit')")
    @Log(title = "项目", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ProjectInfo projectInfo)
    {

        projectInfo.setUpdateBy(getUsername());
        projectInfo.setUpdateTime(DateUtils.getNowDate());

        return toAjax(projectInfoService.updateProjectInfo(projectInfo));
    }

    /**
     * 删除项目
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:remove')")
    @Log(title = "项目", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {

        List<Long> failIds = projectInfoService.deleteProjectInfoByIds(ids);
        if(failIds.size() == 0){
            return success();
        }

        StringBuilder sb = new StringBuilder();
        for (Long id : failIds) {
            ProjectInfo projectInfo = projectInfoService.selectProjectInfoById(id);
            if(projectInfo != null){
                sb.append("合同编号：").append(projectInfo.getProjectCode())
                        .append("，项目名称：").append(projectInfo.getProjectName())
                        .append("<br>");
            }
        }

        String message = "以下项目存在相关信息，删除失败：<br>" + sb;

        return error(message);
    }


    /**
     * 导出项目列表
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:export')")
    @Log(title = "项目", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ProjectInfo projectInfo) throws IOException {

        ProjectInfo p = projectInfoService.selectProjectInfoById(projectInfo.getId());

        String title = "项目名称：" + p.getProjectName() + "（" + p.getProjectCode() + "）";

        // 动态表头
        List<List<String>> headList = new ArrayList<>();
        //head0.add("序号");
        List<String> head1 = new ArrayList<>();
        head1.add(title);
        head1.add("分部分项工程名称");
        List<String> head2 = new ArrayList<>();
        head2.add(title);
        head2.add("累计2023年账面工程施工借方发生额合计（不含税）");
        List<String> head3 = new ArrayList<>();
        head3.add(title);
        head3.add("累计已发生成本（含税）");
        List<String> head4 = new ArrayList<>();
        head4.add(title);
        head4.add("已发生成本理论进项税额");
        List<String> head5 = new ArrayList<>();
        head5.add(title);
        head5.add("合同额（含税）");
        List<String> head6 = new ArrayList<>();
        head6.add(title);
        head6.add("预计总成本理论进项税额");
        List<String> head7 = new ArrayList<>();
        head7.add(title);
        head7.add("完成进度");
        List<String> head8 = new ArrayList<>();
        head8.add(title);
        head8.add("备注");
        headList.add(head1);
        headList.add(head2);
        headList.add(head3);
        headList.add(head4);
        headList.add(head5);
        headList.add(head6);
        headList.add(head7);
        headList.add(head8);

        // 响应头
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 设置文件名
        //String fileName = URLEncoder.encode(p.getProjectName() + "年度盈亏分析表", "UTF-8");
        // 设置响应头，以附件形式下载，指定文件名
        //response.addHeader("Access-Control-Allow-Origin", "*");
        //response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        // 设置表头样式
        WriteCellStyle headCellStyle = new WriteCellStyle();
        WriteFont headFont = new WriteFont();
        headFont.setFontHeightInPoints((short) 10); // 设置字体大小
        headCellStyle.setWriteFont(headFont);
        headCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置背景颜色
        headCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //垂直居中,水平居中
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headCellStyle.setBorderLeft(BorderStyle.THIN);
        headCellStyle.setBorderTop(BorderStyle.THIN);
        headCellStyle.setBorderRight(BorderStyle.THIN);
        headCellStyle.setBorderBottom(BorderStyle.THIN);
        headCellStyle.setWrapped(true);

        // 创建内容样式
        WriteCellStyle contentCellStyle = new WriteCellStyle();
        WriteFont contentFont = new WriteFont();
        contentFont.setFontHeightInPoints((short) 10); // 设置字体大小
        contentCellStyle.setWriteFont(contentFont);
        contentCellStyle.setWrapped(true); // 设置文字过长时自动换行
        //垂直居中,水平居中
        contentCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentCellStyle.setBorderLeft(BorderStyle.THIN);
        contentCellStyle.setBorderTop(BorderStyle.THIN);
        contentCellStyle.setBorderRight(BorderStyle.THIN);
        contentCellStyle.setBorderBottom(BorderStyle.THIN);


        // 创建 ExcelWriter 对象
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).relativeHeadRowIndex(2).build();

        // 创建 汇总Sheet 对象
        WriteSheet summarySheet = EasyExcel.writerSheet(0, "汇总")
                .head(headList)
                .registerWriteHandler(new SummaryBackgroundHandler(IndexedColors.PALE_BLUE))
                .registerWriteHandler(new SummarySheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();

        Summary itemSummary = projectInfoService.selectItemSummary(p.getProjectCode());

        Summary laborSummary = projectInfoService.selectLaborSummary(p.getProjectCode());

        Summary directSummary = projectInfoService.selectDirectSummary(p.getProjectCode());

        Summary indirectSummary = projectInfoService.selectIndirectSummary(p.getProjectCode());


        if (!(itemSummary != null && laborSummary != null && directSummary != null)) {
            throw new RuntimeException("summary对象为空");
        }

        BigDecimal realCost = itemSummary.getRealTotalWithTax().add(laborSummary.getRealTotalWithTax()).add(directSummary.getRealTotalWithTax());
        BigDecimal tax = itemSummary.getTax().add(laborSummary.getTax()).add(directSummary.getTax());
        BigDecimal cost = p.getProcurementCost().add(p.getIndirectCost()).subtract(tax);
        BigDecimal profit = p.getOutput().subtract(cost);
        BigDecimal contract = itemSummary.getContractWithTax().add(laborSummary.getContractWithTax()).add(directSummary.getContractWithTax());
        BigDecimal expectTax = itemSummary.getExpectTax().add(laborSummary.getExpectTax()).add(directSummary.getExpectTax());

        //规定百分数形式
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        // 计算利润率
        BigDecimal profitRate;
        if (p.getOutput() != null && BigDecimal.ZERO.compareTo(p.getOutput()) != 0) {
            profitRate = profit.divide(p.getOutput(), 4, RoundingMode.HALF_UP);
        } else {
            profitRate = BigDecimal.ZERO;
        }


        int result1 = realCost.compareTo(p.getProcurementCost());
        log.info("汇总相加的累计采购成本：" + realCost + " ，项目汇总中的累计采购成本：" + p.getProcurementCost());
        int result2 = tax.compareTo(p.getTotalTax());
        log.info("计算得到的合计成本：" + cost + " ，项目实体中的合计成本：" + p.getCost());
        int result3 = cost.compareTo(p.getCost());

        if (!(result1 == 0)) {
            throw new IllegalStateException("realCost计算有误。");
        }
        if (!(result2 == 0)) {
            throw new IllegalStateException("totalTax计算有误。");
        }
        if (!(result3 == 0)) {
            throw new IllegalStateException("cost计算有误。");
        }

        List<List<Object>> projectInfoDataList = new ArrayList<>();
        List<Object> rowData1 = new ArrayList<>();
        rowData1.add("采购成本");
        rowData1.add(null);
        rowData1.add(realCost);
        rowData1.add(tax);
        rowData1.add(contract);
        rowData1.add(expectTax);
        if(contract.compareTo(BigDecimal.ZERO) != 0){
            rowData1.add(decimalFormat.format(realCost.divide(contract, 4, RoundingMode.HALF_UP)));
        }else {
            rowData1.add(decimalFormat.format(0.00));
        }

        rowData1.add(p.getRemark());


        List<Object> rowData2 = new ArrayList<>();
        rowData2.add("材料采购");
        rowData2.add(null);
        rowData2.add(itemSummary.getRealTotalWithTax());
        rowData2.add(itemSummary.getTax());
        rowData2.add(itemSummary.getContractWithTax());
        rowData2.add(itemSummary.getExpectTax());
        if(itemSummary.getExpectTax().compareTo(BigDecimal.ZERO) != 0){
            rowData2.add(decimalFormat.format(itemSummary.getRealTotalWithTax().divide(itemSummary.getContractWithTax(), 4, RoundingMode.HALF_UP)));
        }else {
            rowData2.add(0);
        }
        rowData2.add(null);

        List<Object> rowData3 = new ArrayList<>();
        rowData3.add("劳务费");
        rowData3.add(null);
        rowData3.add(laborSummary.getRealTotalWithTax());
        rowData3.add(laborSummary.getTax());
        rowData3.add(laborSummary.getContractWithTax());
        rowData3.add(laborSummary.getExpectTax());
        if(laborSummary.getExpectTax().compareTo(BigDecimal.ZERO) != 0){
            rowData3.add(decimalFormat.format(laborSummary.getRealTotalWithTax().divide(laborSummary.getContractWithTax(), 4, RoundingMode.HALF_UP)));
        }else {
            rowData3.add(0);
        }
        rowData3.add(null);

        List<Object> rowData4 = new ArrayList<>();
        rowData4.add("直接费用");
        rowData4.add(null);
        rowData4.add(directSummary.getRealTotalWithTax());
        rowData4.add(directSummary.getTax());
        rowData4.add(directSummary.getContractWithTax());
        rowData4.add(directSummary.getExpectTax());
        if(directSummary.getExpectTax().compareTo(BigDecimal.ZERO) != 0){
            rowData4.add(decimalFormat.format(directSummary.getRealTotalWithTax().divide(directSummary.getContractWithTax(), 4, RoundingMode.HALF_UP)));
        }else {
            rowData4.add(0);
        }
        rowData4.add(null);

        List<Object> rowData5 = new ArrayList<>();
        rowData5.add("其他间接费用");
        rowData5.add(indirectSummary.getTotalNoTax());
        rowData5.add(indirectSummary.getRealTotalWithTax());
        rowData5.add(indirectSummary.getTax());
        rowData5.add(indirectSummary.getContractWithTax());
        rowData5.add(indirectSummary.getExpectTax());
        rowData5.add(null);
        rowData5.add(null);

        Stream.of(rowData1, rowData2, rowData3, rowData4, rowData5)
                .forEach(projectInfoDataList::add);

        Indirect query = new Indirect();
        query.setProjectCode(p.getProjectCode());
        List<Indirect> indirectSummaryList = indirectService.selectIndirectList(query);
        //if (!(indirectSummaryList.size() == 7)) {
        //    throw new RuntimeException("请补全间接费用。");
        //}

        // 创建一个 Map 用于存储已有的间接费用数据，键为间接费用名称，值为对应的 Indirect 对象
        Map<String, Indirect> existingIndirectMap = new HashMap<>();
        for (Indirect i : indirectSummaryList) {
            existingIndirectMap.put(i.getIndirectName(), i);
        }

        List<String> allIndirectNames = Arrays.asList("财务费用", "人工费", "业务招待费", "其它费用", "办公费", "安全文明措施费", "低值易耗品摊销");

        for (String indirectName : allIndirectNames) {
            if (!existingIndirectMap.containsKey(indirectName)) {
                List<Object> rowData6 = new ArrayList<>();
                rowData6.add(indirectName); // 间接费用名称
                rowData6.add(null); // 总金额
                rowData6.add(null); // 实际总金额
                rowData6.add(null); // 未清金额
                rowData6.add(null); // 累计合同金额
                rowData6.add(null); // 累计已发生金额
                rowData6.add(null); // 未结算金额
                rowData6.add(null); // 备注
                projectInfoDataList.add(rowData6);
            }else{
                Indirect indirect = existingIndirectMap.get(indirectName);
                List<Object> rowData6 = new ArrayList<>();
                rowData6.add(indirect.getIndirectName());
                rowData6.add(indirect.getTotalNoTax());
                rowData6.add(indirect.getRealTotalWithTax());
                rowData6.add(null);
                rowData6.add(indirect.getContractWithTax());
                rowData6.add(null);
                rowData6.add(null);
                rowData6.add(indirect.getRemark());
                projectInfoDataList.add(rowData6);
            }
        }

        List<Object> rowData13 = new ArrayList<>();
        rowData13.add("理论增值税");
        rowData13.add(null);
        rowData13.add(null);
        rowData13.add(null);
        rowData13.add(null);
        rowData13.add(null);
        rowData13.add(null);
        rowData13.add(null);

        List<Object> rowData14 = new ArrayList<>();
        rowData14.add("理论销项税额");

        List<Object> rowData15 = new ArrayList<>();
        rowData15.add("理论进项税额");

        List<Object> rowData16 = new ArrayList<>();
        rowData16.add("开工-2023年累计除税成本");
        rowData16.add(cost);
        rowData16.add(null);
        rowData16.add(null);
        rowData16.add(null);
        rowData16.add(null);
        rowData16.add(null);
        rowData16.add(null);

        List<Object> rowData17 = new ArrayList<>();
        rowData17.add("开工-2023年累计除税产值");
        rowData17.add(p.getOutput());
        rowData17.add(null);
        rowData17.add(null);
        rowData17.add(null);
        rowData17.add(null);
        rowData17.add(null);
        rowData17.add(null);

        List<Object> rowData18 = new ArrayList<>();
        rowData18.add("利润");
        rowData18.add(profit);
        rowData18.add(null);
        rowData18.add(null);
        rowData18.add(null);
        rowData18.add(null);
        rowData18.add(null);
        rowData18.add(null);

        List<Object> rowData19 = new ArrayList<>();
        rowData19.add("利润率");
        rowData19.add(decimalFormat.format(profitRate));
        rowData19.add(null);
        rowData19.add(null);
        rowData19.add(null);
        rowData19.add(null);
        rowData19.add(null);
        rowData19.add(null);

        Stream.of(rowData13, rowData14, rowData15, rowData16, rowData17, rowData18, rowData19)
                .forEach(projectInfoDataList::add);

        // 写入数据
        excelWriter.write(projectInfoDataList, summarySheet);


        // 定义合计属性
        BigDecimal totalRealTotalWithTax = BigDecimal.ZERO;
        BigDecimal totalTax = BigDecimal.ZERO;
        BigDecimal totalContract = BigDecimal.ZERO;
        BigDecimal totalExpectTax = BigDecimal.ZERO;

        //序号
        long no = 0;
        long noContractNo = 0;

        int lastRowIndex;

        List<NoContract> noContractList = new ArrayList<>();
        List<ProcurementDetail> detailHaveContractList = new ArrayList<>();
        List<Direct> directHaveContractList = new ArrayList<>();
        List<Labor> laborHaveContractList = new ArrayList<>();

        // 写入材料采购明细数据
        ProcurementDetail procurementDetail = new ProcurementDetail();
        procurementDetail.setProjectCode(p.getProjectCode());
        List<ProcurementDetail> procurementDetailList = procurementDetailService.selectProcurementDetailList(procurementDetail);
        // 计算合计
        for (ProcurementDetail detail : procurementDetailList) {
            if(detail.getContractCode() != null && !("".equals(detail.getContractCode()))){
                totalRealTotalWithTax = totalRealTotalWithTax.add(detail.getRealTotalWithTax());
                totalTax = totalTax.add(detail.getTax());
                totalContract = totalContract.add(detail.getContractWithTax());
                totalExpectTax = totalExpectTax.add(detail.getExpectTax());
                detail.setNo(++no);
                detailHaveContractList.add(detail);
            }else {
                NoContract noContract = new NoContract();
                BeanUtils.copyProperties(detail, noContract);
                noContract.setNoContractName(detail.getItemName());
                noContract.setNo(++noContractNo);
                noContractList.add(noContract);
            }
        }
        // 创建合计对象
        ProcurementDetail totalDetail = new ProcurementDetail();
        totalDetail.setItemName("合计");
        totalDetail.setContractWithTax(totalContract);
        totalDetail.setRealTotalWithTax(totalRealTotalWithTax);
        totalDetail.setTax(totalTax);
        totalDetail.setExpectTax(totalExpectTax);
        // 将合计对象添加到列表中
        detailHaveContractList.add(totalDetail);
        lastRowIndex = detailHaveContractList.size() - 1;
        log.info("lastRowIndex：" + lastRowIndex);
        // 创建 材料采购明细Sheet 对象
        WriteSheet detailSheet = EasyExcel.writerSheet(1, "材料采购明细")
                .head(ProcurementDetail.class)
                .registerWriteHandler(new LastRowBackgroundHandler(IndexedColors.YELLOW, lastRowIndex))
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(detailHaveContractList, detailSheet);


        // 写入劳务费数据
        Labor labor = new Labor();
        labor.setProjectCode(p.getProjectCode());
        List<Labor> laborList = laborService.selectLaborList(labor);
        // 计算合计
        totalContract = BigDecimal.ZERO;
        totalRealTotalWithTax = BigDecimal.ZERO;
        totalTax = BigDecimal.ZERO;
        totalExpectTax = BigDecimal.ZERO;
        no = 0;
        noContractNo = 0;
        for (Labor l : laborList) {
            if(l.getContractCode() != null && !("".equals(l.getContractCode()))){
                totalRealTotalWithTax = totalRealTotalWithTax.add(l.getRealTotalWithTax());
                totalTax = totalTax.add(l.getTax());
                totalContract = totalContract.add(l.getContractWithTax());
                totalExpectTax = totalExpectTax.add(l.getExpectTax());
                l.setNo(++no);
                laborHaveContractList.add(l);
            }else {
                NoContract noContract = new NoContract();
                BeanUtils.copyProperties(l, noContract);
                noContract.setNoContractName(l.getLaborName());
                noContract.setNo(++noContractNo);
                noContractList.add(noContract);
            }
        }
        // 创建合计对象
        Labor totalLabor = new Labor();
        totalLabor.setLaborName("合计");
        totalLabor.setContractWithTax(totalContract);
        totalLabor.setRealTotalWithTax(totalRealTotalWithTax);
        totalLabor.setTax(totalTax);
        totalLabor.setExpectTax(totalExpectTax);
        // 将合计对象添加到列表中
        laborHaveContractList.add(totalLabor);
        lastRowIndex = laborHaveContractList.size() - 1;
        // 创建 劳务费Sheet 对象
        WriteSheet laborSheet = EasyExcel.writerSheet(2, "劳务费")
                .head(Labor.class)
                .registerWriteHandler(new LastRowBackgroundHandler(IndexedColors.YELLOW, lastRowIndex))
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(laborHaveContractList, laborSheet);


        // 写入直接费用数据
        Direct direct = new Direct();
        direct.setProjectCode(p.getProjectCode());
        List<Direct> directList = directService.selectDirectList(direct);
        // 计算合计
        totalContract = BigDecimal.ZERO;
        totalRealTotalWithTax = BigDecimal.ZERO;
        totalTax = BigDecimal.ZERO;
        totalExpectTax = BigDecimal.ZERO;
        no = 0;
        noContractNo = 0;
        for (Direct d : directList) {
            if(d.getContractCode() != null && !("".equals(d.getContractCode()))){
                totalRealTotalWithTax = totalRealTotalWithTax.add(d.getRealTotalWithTax());
                totalTax = totalTax.add(d.getTax());
                totalContract = totalContract.add(d.getContractWithTax());
                totalExpectTax = totalExpectTax.add(d.getExpectTax());
                d.setNo(++no);
                directHaveContractList.add(d);
            }else {
                NoContract noContract = new NoContract();
                BeanUtils.copyProperties(d, noContract);
                noContract.setNoContractName(d.getDirectName());
                noContract.setNo(++noContractNo);
                noContractList.add(noContract);
            }
        }
        // 创建合计对象
        Direct totalDirect = new Direct();
        totalDirect.setDirectName("合计");
        totalDirect.setContractWithTax(totalContract);
        totalDirect.setRealTotalWithTax(totalRealTotalWithTax);
        totalDirect.setTax(totalTax);
        totalDirect.setExpectTax(totalExpectTax);
        // 将合计对象添加到列表中
        directHaveContractList.add(totalDirect);
        lastRowIndex = directHaveContractList.size() - 1;
        // 创建 直接费用Sheet 对象
        WriteSheet directSheet = EasyExcel.writerSheet(3, "专业分包")
                .head(Direct.class)
                .registerWriteHandler(new LastRowBackgroundHandler(IndexedColors.YELLOW, lastRowIndex))
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(directHaveContractList, directSheet);

        // 计算合计
        totalRealTotalWithTax = BigDecimal.ZERO;
        totalTax = BigDecimal.ZERO;
        for (NoContract n : noContractList) {
            totalRealTotalWithTax = totalRealTotalWithTax.add(n.getRealTotalWithTax());
            totalTax = totalTax.add(n.getTax());
        }
        // 创建合计对象
        NoContract totalNoContract = new NoContract();
        totalNoContract.setNoContractName("合计");
        totalNoContract.setRealTotalWithTax(totalRealTotalWithTax);
        totalNoContract.setTax(totalTax);
        // 将合计对象添加到列表中
        noContractList.add(totalNoContract);
        lastRowIndex = noContractList.size() - 1;
        // 创建 无合同费用Sheet 对象
        WriteSheet noContractSheet = EasyExcel.writerSheet(4, "无合同费用")
                .head(NoContract.class)
                .registerWriteHandler(new LastRowBackgroundHandler(IndexedColors.YELLOW, lastRowIndex))
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(noContractList, noContractSheet);

        // 写入间接费用数据
        Indirect indirect = new Indirect();
        indirect.setProjectCode(p.getProjectCode());
        List<Indirect> indirectList = indirectService.selectIndirectList(indirect);
        List<Indirect> indirectListWithNo = new ArrayList<>();
        no = 0;
        for (Indirect i : indirectList) {
            i.setNo(++no);
            indirectListWithNo.add(i);
        }

        // 创建 间接费用Sheet 对象
        WriteSheet indirectSheet = EasyExcel.writerSheet(5, "间接费用")
                .head(Indirect.class)
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(indirectListWithNo, indirectSheet);

        // 写入产值数据
        Output outputQuery = new Output();
        outputQuery.setProjectCode(p.getProjectCode());
        Output output = outputService.selectOutput(outputQuery);
        List<Output> outputList = new ArrayList<>();

        // 创建 产值Sheet 对象
        String filePath = System.getProperty("user.dir") + File.separator + output.getRemark();
        output.setRemark("请点击查看附件");
        outputList.add(output);
        WriteSheet outputSheet = EasyExcel.writerSheet(6, "产值")
                .head(Output.class)
                .registerWriteHandler(new OutputHandler(output.getProjectName()))
                .registerWriteHandler(new AttachmentWriteHandler(filePath, "备注"))
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 40, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(outputList, outputSheet);

        excelWriter.finish();

    }


    /**
     * 汇总项目列表
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:projectInfo:summary')")
    @Log(title = "项目", businessType = BusinessType.EXPORT)
    @PostMapping("/summary")
    public void exportProjectSummary(HttpServletResponse response,
                                     @RequestParam("start")String start,
                                     @RequestParam("end")String end) throws IOException{

        log.info("start: " + start + ", end: " + end);

        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        List<ProjectInfo> projectInfoList = projectInfoService.selectProjectInfoList(new ProjectInfo());
        for (ProjectInfo pi : projectInfoList) {
            ProjectSummary ps = new ProjectSummary();
            ps.setAreaId(pi.getAreaId());
            ps.setTotalContract(pi.getTotalContract());
            if(pi.getAssessRate() != null){
                ps.setAssessRate(pi.getAssessRate());
            }else {
                ps.setAssessRate(0.00);
            }
            ps.setProjectCode(pi.getProjectCode());
            ps.setProjectName(pi.getProjectName());
            ps.setTotalOutput(pi.getOutput());
            ps.setTotalCost(pi.getCost());
            if(((pi.getOutput().subtract(pi.getCost())).compareTo(pi.getProfit())) !=0 ){
                throw new IllegalStateException("realCost计算有误。");
            }
            ps.setTotalProfit(pi.getProfit());
            if(pi.getOutput().compareTo(BigDecimal.ZERO) != 0){
                ps.setTotalProfitRate((pi.getProfit().divide(pi.getOutput(), 4, RoundingMode.HALF_UP)).doubleValue());
            }else {
                ps.setTotalProfitRate(null);
            }
            // 此处略过财务利息
            if(projectInfoService.checkProjectSummary(ps.getProjectCode()) == 0){
                projectInfoService.insertProjectSummary(ps);
            }else{
                projectInfoService.updateProjectSummaryByEntity(ps);
            }
        }

        projectInfoService.updateProjectSummary();

        // 设置表头样式
        WriteCellStyle headCellStyle = new WriteCellStyle();
        WriteFont headFont = new WriteFont();
        headFont.setFontHeightInPoints((short) 8); // 设置字体大小
        headCellStyle.setWriteFont(headFont);
        headCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置背景颜色
        headCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //垂直居中,水平居中
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headCellStyle.setBorderLeft(BorderStyle.THIN);
        headCellStyle.setBorderTop(BorderStyle.THIN);
        headCellStyle.setBorderRight(BorderStyle.THIN);
        headCellStyle.setBorderBottom(BorderStyle.THIN);
        headCellStyle.setWrapped(true);

        // 创建内容样式
        WriteCellStyle contentCellStyle = new WriteCellStyle();
        WriteFont contentFont = new WriteFont();
        contentFont.setFontHeightInPoints((short) 8); // 设置字体大小
        contentCellStyle.setWriteFont(contentFont);
        contentCellStyle.setWrapped(true); // 设置文字过长时自动换行
        //垂直居中,水平居中
        contentCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentCellStyle.setBorderLeft(BorderStyle.THIN);
        contentCellStyle.setBorderTop(BorderStyle.THIN);
        contentCellStyle.setBorderRight(BorderStyle.THIN);
        contentCellStyle.setBorderBottom(BorderStyle.THIN);

        List<SectorSummary> sectorSummaryList = new ArrayList<>();
        SectorSummary sectorSummary1 = new SectorSummary();
        SectorSummary sectorSummary2 = new SectorSummary();
        SectorSummary sectorSummary3 = new SectorSummary();
        SectorSummary sectorSummary4 = new SectorSummary();
        SectorSummary sectorSummary5 = new SectorSummary();
        SectorSummary sectorSummary6 = new SectorSummary();
        SectorSummary sectorSummary7 = new SectorSummary();
        BigDecimal output = BigDecimal.ZERO;
        BigDecimal cost = BigDecimal.ZERO;
        BigDecimal indirectCost = BigDecimal.ZERO;
        BigDecimal profit = BigDecimal.ZERO;
        BigDecimal profitRate = BigDecimal.ZERO;
        BigDecimal indirectCostRate = BigDecimal.ZERO;

        BigDecimal totalOutput = BigDecimal.ZERO;
        BigDecimal totalCost = BigDecimal.ZERO;
        BigDecimal totalIndirectCost = BigDecimal.ZERO;
        BigDecimal totalProfit = BigDecimal.ZERO;

        // 创建 ExcelWriter 对象
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).relativeHeadRowIndex(2).build();

        // 房建板块
        long no = 0;
        sectorSummary1.setSectorName("房建板块");
        List<ProjectSummary> projectSummaryList3 = projectInfoService.selectProjectSummaryList(3);
        for (ProjectSummary p : projectSummaryList3) {
            p.setNo(++no);
            output = output.add(p.getLastYearOutput());
            cost = cost.add(p.getLastYearCost());
            indirectCost = indirectCost.add(p.getInterest().add(p.getOther()));
            profit = profit.add(p.getLastYearProfit());
            if(BigDecimal.ZERO.compareTo(output) != 0){
                profitRate = profit.divide(output, 4, RoundingMode.HALF_UP);
                indirectCostRate = indirectCost.divide(output, 4, RoundingMode.HALF_UP);
            }else {
                profitRate = BigDecimal.ZERO;
                indirectCostRate = BigDecimal.ZERO;
            }
        }
        totalOutput = totalOutput.add(output);
        totalCost = totalCost.add(cost);
        totalIndirectCost = totalIndirectCost.add(indirectCost);
        totalProfit = totalProfit.add(profit);

        sectorSummary1.setLastYearOutput(output);
        sectorSummary1.setLastYearCost(cost);
        sectorSummary1.setLastYearIndirectCost(indirectCost);
        sectorSummary1.setLastYearProfit(profit);
        sectorSummary1.setLastYearProfitRate(decimalFormat.format(profitRate));
        sectorSummary1.setLastYearIndirectRate(decimalFormat.format(indirectCostRate));
        sectorSummaryList.add(sectorSummary1);
        // 创建 汇总Sheet 对象
        WriteSheet fjSheet = EasyExcel.writerSheet(2, "房建板块")
                .head(ProjectSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(projectSummaryList3, fjSheet);

        // 海外板块
        List<ProjectSummary> projectSummaryList4 = projectInfoService.selectProjectSummaryList(4);
        no = 0;
        sectorSummary2.setSectorName("海外板块");
        output = BigDecimal.ZERO;
        cost = BigDecimal.ZERO;
        indirectCost = BigDecimal.ZERO;
        profit = BigDecimal.ZERO;
        profitRate = BigDecimal.ZERO;
        indirectCostRate = BigDecimal.ZERO;
        for (ProjectSummary p : projectSummaryList4) {
            p.setNo(++no);
            output = output.add(p.getLastYearOutput());
            cost = cost.add(p.getLastYearCost());
            indirectCost = indirectCost.add(p.getInterest().add(p.getOther()));
            profit = profit.add(p.getLastYearProfit());
            if(BigDecimal.ZERO.compareTo(output) != 0){
                profitRate = profit.divide(output, 4, RoundingMode.HALF_UP);
                indirectCostRate = indirectCost.divide(output, 4, RoundingMode.HALF_UP);
            }else {
                profitRate = BigDecimal.ZERO;
                indirectCostRate = BigDecimal.ZERO;
            }

        }
        totalOutput = totalOutput.add(output);
        totalCost = totalCost.add(cost);
        totalIndirectCost = totalIndirectCost.add(indirectCost);
        totalProfit = totalProfit.add(profit);

        sectorSummary2.setLastYearOutput(output);
        sectorSummary2.setLastYearCost(cost);
        sectorSummary2.setLastYearIndirectCost(indirectCost);
        sectorSummary2.setLastYearProfit(profit);
        sectorSummary2.setLastYearProfitRate(decimalFormat.format(profitRate));
        sectorSummary2.setLastYearIndirectRate(decimalFormat.format(indirectCostRate));
        sectorSummaryList.add(sectorSummary2);
        // 创建 汇总Sheet 对象
        WriteSheet hwSheet = EasyExcel.writerSheet(3, "海外板块")
                .head(ProjectSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(projectSummaryList4, hwSheet);

        // 市政板块
        List<ProjectSummary> projectSummaryList5 = projectInfoService.selectProjectSummaryList(5);
        no = 0;
        sectorSummary3.setSectorName("市政板块");
        output = BigDecimal.ZERO;
        cost = BigDecimal.ZERO;
        indirectCost = BigDecimal.ZERO;
        profit = BigDecimal.ZERO;
        profitRate = BigDecimal.ZERO;
        indirectCostRate = BigDecimal.ZERO;
        for (ProjectSummary p : projectSummaryList5) {
            p.setNo(++no);
            output = output.add(p.getLastYearOutput());
            cost = cost.add(p.getLastYearCost());
            indirectCost = indirectCost.add(p.getInterest().add(p.getOther()));
            profit = profit.add(p.getLastYearProfit());
            if(BigDecimal.ZERO.compareTo(output) != 0){
                profitRate = profit.divide(output, 4, RoundingMode.HALF_UP);
                indirectCostRate = indirectCost.divide(output, 4, RoundingMode.HALF_UP);
            }else {
                profitRate = BigDecimal.ZERO;
                indirectCostRate = BigDecimal.ZERO;
            }

        }
        totalOutput = totalOutput.add(output);
        totalCost = totalCost.add(cost);
        totalIndirectCost = totalIndirectCost.add(indirectCost);
        totalProfit = totalProfit.add(profit);

        sectorSummary3.setLastYearOutput(output);
        sectorSummary3.setLastYearCost(cost);
        sectorSummary3.setLastYearIndirectCost(indirectCost);
        sectorSummary3.setLastYearProfit(profit);
        sectorSummary3.setLastYearProfitRate(decimalFormat.format(profitRate));
        sectorSummary3.setLastYearIndirectRate(decimalFormat.format(indirectCostRate));
        sectorSummaryList.add(sectorSummary3);
        // 创建 汇总Sheet 对象
        WriteSheet szSheet = EasyExcel.writerSheet(4, "市政板块")
                .head(ProjectSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(projectSummaryList5, szSheet);

        // 开发板块
        List<ProjectSummary> projectSummaryList6 = projectInfoService.selectProjectSummaryList(6);
        no = 0;
        sectorSummary4.setSectorName("开发板块");
        output = BigDecimal.ZERO;
        cost = BigDecimal.ZERO;
        indirectCost = BigDecimal.ZERO;
        profit = BigDecimal.ZERO;
        profitRate = BigDecimal.ZERO;
        indirectCostRate = BigDecimal.ZERO;
        for (ProjectSummary p : projectSummaryList6) {
            p.setNo(++no);
            output = output.add(p.getLastYearOutput());
            cost = cost.add(p.getLastYearCost());
            indirectCost = indirectCost.add(p.getInterest().add(p.getOther()));
            profit = profit.add(p.getLastYearProfit());
            if(BigDecimal.ZERO.compareTo(output) != 0){
                profitRate = profit.divide(output, 4, RoundingMode.HALF_UP);
                indirectCostRate = indirectCost.divide(output, 4, RoundingMode.HALF_UP);
            }else {
                profitRate = BigDecimal.ZERO;
                indirectCostRate = BigDecimal.ZERO;
            }
        }
        totalOutput = totalOutput.add(output);
        totalCost = totalCost.add(cost);
        totalIndirectCost = totalIndirectCost.add(indirectCost);
        totalProfit = totalProfit.add(profit);

        sectorSummary4.setLastYearOutput(output);
        sectorSummary4.setLastYearCost(cost);
        sectorSummary4.setLastYearIndirectCost(indirectCost);
        sectorSummary4.setLastYearProfit(profit);
        sectorSummary4.setLastYearProfitRate(decimalFormat.format(profitRate));
        sectorSummary4.setLastYearIndirectRate(decimalFormat.format(indirectCostRate));
        sectorSummaryList.add(sectorSummary4);
        // 创建 汇总Sheet 对象
        WriteSheet kfSheet = EasyExcel.writerSheet(5, "开发板块")
                .head(ProjectSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(projectSummaryList6, kfSheet);

        // 鑫辰德
        List<ProjectSummary> projectSummaryList7 = projectInfoService.selectProjectSummaryList(7);
        no = 0;
        sectorSummary5.setSectorName("鑫辰德");
        output = BigDecimal.ZERO;
        cost = BigDecimal.ZERO;
        indirectCost = BigDecimal.ZERO;
        profit = BigDecimal.ZERO;
        profitRate = BigDecimal.ZERO;
        indirectCostRate = BigDecimal.ZERO;
        for (ProjectSummary p : projectSummaryList7) {
            p.setNo(++no);
            output = output.add(p.getLastYearOutput());
            cost = cost.add(p.getLastYearCost());
            indirectCost = indirectCost.add(p.getInterest().add(p.getOther()));
            profit = profit.add(p.getLastYearProfit());
            if(BigDecimal.ZERO.compareTo(output) != 0){
                profitRate = profit.divide(output, 4, RoundingMode.HALF_UP);
                indirectCostRate = indirectCost.divide(output, 4, RoundingMode.HALF_UP);
            }else {
                profitRate = BigDecimal.ZERO;
                indirectCostRate = BigDecimal.ZERO;
            }
        }
        totalOutput = totalOutput.add(output);
        totalCost = totalCost.add(cost);
        totalIndirectCost = totalIndirectCost.add(indirectCost);
        totalProfit = totalProfit.add(profit);

        sectorSummary5.setLastYearOutput(output);
        sectorSummary5.setLastYearCost(cost);
        sectorSummary5.setLastYearIndirectCost(indirectCost);
        sectorSummary5.setLastYearProfit(profit);
        sectorSummary5.setLastYearProfitRate(decimalFormat.format(profitRate));
        sectorSummary5.setLastYearIndirectRate(decimalFormat.format(indirectCostRate));
        sectorSummaryList.add(sectorSummary5);
        // 创建 汇总Sheet 对象
        WriteSheet xcdSheet = EasyExcel.writerSheet(6, "鑫辰德")
                .head(ProjectSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(projectSummaryList7, xcdSheet);

        // 远融
        List<ProjectSummary> projectSummaryList8 = projectInfoService.selectProjectSummaryList(8);
        no = 0;
        sectorSummary6.setSectorName("远融");
        output = BigDecimal.ZERO;
        cost = BigDecimal.ZERO;
        indirectCost = BigDecimal.ZERO;
        profit = BigDecimal.ZERO;
        profitRate = BigDecimal.ZERO;
        indirectCostRate = BigDecimal.ZERO;
        for (ProjectSummary p : projectSummaryList8) {
            p.setNo(++no);
            output = output.add(p.getLastYearOutput());
            cost = cost.add(p.getLastYearCost());
            indirectCost = indirectCost.add(p.getInterest().add(p.getOther()));
            profit = profit.add(p.getLastYearProfit());
            if(BigDecimal.ZERO.compareTo(output) != 0){
                profitRate = profit.divide(output, 4, RoundingMode.HALF_UP);
                indirectCostRate = indirectCost.divide(output, 4, RoundingMode.HALF_UP);
            }else {
                profitRate = BigDecimal.ZERO;
                indirectCostRate = BigDecimal.ZERO;
            }


        }
        totalOutput = totalOutput.add(output);
        totalCost = totalCost.add(cost);
        totalIndirectCost = totalIndirectCost.add(indirectCost);
        totalProfit = totalProfit.add(profit);

        sectorSummary6.setLastYearOutput(output);
        sectorSummary6.setLastYearCost(cost);
        sectorSummary6.setLastYearIndirectCost(indirectCost);
        sectorSummary6.setLastYearProfit(profit);
        sectorSummary6.setLastYearProfitRate(decimalFormat.format(profitRate));
        sectorSummary6.setLastYearIndirectRate(decimalFormat.format(indirectCostRate));
        sectorSummaryList.add(sectorSummary6);
        // 创建 汇总Sheet 对象
        WriteSheet yrSheet = EasyExcel.writerSheet(7, "远融")
                .head(ProjectSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(projectSummaryList8, yrSheet);
        sectorSummary7.setSectorName("合计");
        sectorSummary7.setLastYearOutput(totalOutput);
        sectorSummary7.setLastYearCost(totalCost);
        sectorSummary7.setLastYearIndirectCost(totalIndirectCost);
        sectorSummary7.setLastYearProfit(totalProfit);
        if(BigDecimal.ZERO.compareTo(totalOutput) != 0){
            sectorSummary7.setLastYearProfitRate(decimalFormat.format(totalProfit.divide(totalOutput, 4, RoundingMode.HALF_UP)));
            sectorSummary7.setLastYearIndirectRate(decimalFormat.format(totalIndirectCost.divide(totalOutput, 4, RoundingMode.HALF_UP)));
        }else {
            sectorSummary7.setLastYearProfitRate(decimalFormat.format(0));
            sectorSummary7.setLastYearIndirectRate(decimalFormat.format(0));
        }
        sectorSummaryList.add(sectorSummary7);

        // 创建 12月汇总Sheet 对象
        WriteSheet yearSummarySheet = EasyExcel.writerSheet(1, "12月")
                .head(SectorSummary.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(sectorSummaryList, yearSummarySheet);

        String year = String.valueOf(LocalDate.now().minusYears(1).getYear());
        for (int i = 3; i <= 8; i++) {
            projectInfoService.insertAnnualMetrics(i, year);
        }
        // 更新并获取年度指标数据
        projectInfoService.updateAnnualMetrics();
        List<AnnualMetrics> annualMetricsList = projectInfoService.getAnnualMetricsList(year);
        List<AnnualMetrics> newAnnualMetricsList = new ArrayList<>();
        int annualNo = 0;
        // 创建合计对象
        AnnualMetrics annualMetrics = new AnnualMetrics();
        annualMetrics.setSectorName("合计");
        annualMetrics.setContractMetrics(BigDecimal.ZERO);
        annualMetrics.setContractReal(BigDecimal.ZERO);
        annualMetrics.setOutputMetrics(BigDecimal.ZERO);
        annualMetrics.setOutputReal(BigDecimal.ZERO);
        annualMetrics.setProfitMetrics(BigDecimal.ZERO);
        annualMetrics.setProfitReal(BigDecimal.ZERO);
        annualMetrics.setReceivable(BigDecimal.ZERO);
        annualMetrics.setReceived(BigDecimal.ZERO);
        for (AnnualMetrics a : annualMetricsList) {
            a.setNo(++annualNo);
            a.setSectorName();
            annualMetrics.setContractMetrics(a.getContractMetrics().add(annualMetrics.getContractMetrics()));
            annualMetrics.setContractReal(a.getContractReal().add(annualMetrics.getContractReal()));
            annualMetrics.setOutputMetrics(a.getOutputMetrics().add(annualMetrics.getOutputMetrics()));
            annualMetrics.setOutputReal(a.getOutputReal().add(annualMetrics.getOutputReal()));
            annualMetrics.setProfitMetrics(a.getProfitMetrics().add(annualMetrics.getProfitMetrics()));
            annualMetrics.setProfitReal(a.getProfitReal().add(annualMetrics.getProfitReal()));
            annualMetrics.setReceivable(a.getReceivable().add(annualMetrics.getReceivable()));
            annualMetrics.setReceived(a.getReceived().add(annualMetrics.getReceived()));
            newAnnualMetricsList.add(a);
        }
        annualMetrics.setContractRate(annualMetrics.getContractReal().divide(annualMetrics.getContractMetrics(), 4, RoundingMode.HALF_UP).doubleValue());
        annualMetrics.setOutputRate(annualMetrics.getOutputReal().divide(annualMetrics.getOutputMetrics(), 4, RoundingMode.HALF_UP).doubleValue());
        annualMetrics.setProfitRate(annualMetrics.getProfitReal().divide(annualMetrics.getProfitMetrics(), 4, RoundingMode.HALF_UP).doubleValue());
        annualMetrics.setProfitRateMetrics(annualMetrics.getProfitMetrics().divide(annualMetrics.getOutputMetrics(), 4, RoundingMode.HALF_UP).doubleValue());
        annualMetrics.setPaymentRateMetrics(0.8);
        if(BigDecimal.ZERO.compareTo(annualMetrics.getReceivable()) != 0){
            annualMetrics.setPaymentRateReal(annualMetrics.getReceived().divide(annualMetrics.getReceivable(), 4, RoundingMode.HALF_UP).doubleValue());
        }else {
            annualMetrics.setPaymentRateReal(0.0);
        }
        annualMetrics.setPaymentRateUpDown((annualMetrics.getPaymentRateReal() - annualMetrics.getPaymentRateMetrics()) / annualMetrics.getPaymentRateMetrics());
        newAnnualMetricsList.add(annualMetrics);

        // 创建 年度指标Sheet 对象
        WriteSheet annualMetricsSheet = EasyExcel.writerSheet(0, "年度指标")
                .head(AnnualMetrics.class)
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle, contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20)) // 简单的行高策略：头行高30，内容行高20
                .build();
        excelWriter.write(newAnnualMetricsList, annualMetricsSheet);

        excelWriter.finish();

    }

}
